package cc.owoo.godpen.structure;

import java.util.Iterator;

/**
 * 层级链表
 * Created by nimensei
 * 2022-04-06 上午 01:58
 **/
public class LayerList<T> implements Iterable<T> {
    private final ReverseIterable<T> reverseIterable = new ReverseIterable<>(this);//倒叙迭代器
    private Layer<T> first;// 头层
    private Layer<T> last;// 尾层
    private int size;// 列表大小

    /**
     * 获取第一层
     *
     * @return 层
     */
    public Layer<T> getFirst() {
        return first == null ? first = last = new Layer<>(this) : first;
    }

    /**
     * 获取最后一层
     *
     * @return 层
     */
    public Layer<T> getLast() {
        return last == null ? first = last = new Layer<>(this) : last;
    }

    /**
     * 删除所有层的元素
     *
     * @param item 需要删除的元素
     * @return 是否删除成功
     */
    public boolean remove(T item) {
        boolean flag = false;
        Layer<T> layer = first;
        while (layer != null) {
            flag = flag || layer.remove(item);
            layer = layer.next;
        }
        return false;
    }


    /**
     * 获取列表大小
     *
     * @return 列表大小
     */
    public int size() {
        return Math.max(size, 0);
    }

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            private Layer<T> layer = first;
            private Node<T> node = layer.first;

            @Override
            public boolean hasNext() {
                return layer != null && node != null;
            }

            @Override
            public T next() {
                T item = node.value;
                node = node.next;
                while (node == null) {
                    layer = layer.next;
                    if (layer == null)
                        break;
                    node = layer.first;
                }
                return item;
            }
        };
    }

    /**
     * 获取倒叙迭代器
     *
     * @return 倒叙迭代器
     */
    public ReverseIterable<T> reverse() {
        return reverseIterable;
    }

    /**
     * 倒叙迭代器
     *
     * @param <T> 元素类型
     */
    public record ReverseIterable<T>(LayerList<T> list) implements Iterable<T> {
        @Override
        public Iterator<T> iterator() {
            return new Iterator<T>() {
                private Layer<T> layer = list.last;
                private Node<T> node = layer.last;

                @Override
                public boolean hasNext() {
                    return layer != null && node != null;
                }

                @Override
                public T next() {
                    T item = node.value;
                    node = node.prev;
                    while (node == null) {
                        layer = layer.prev;
                        if (layer == null)
                            break;
                        node = layer.last;
                    }
                    return item;
                }
            };
        }
    }

    /**
     * 层
     *
     * @param <E> 类型
     */
    public static class Layer<E> {
        private final LayerList<E> list;// 列表
        private Layer<E> prev;// 上一层
        private Layer<E> next;// 下一层
        private Node<E> first;// 头节点
        private Node<E> last;// 尾节点

        public Layer(LayerList<E> list) {
            this.list = list;
        }

        /**
         * 添加一个元素
         *
         * @param item 需要添加的元素
         */
        public void add(E item) {
            addLast(item);
        }

        /**
         * 删除元素
         *
         * @param item 需要删除的元素
         * @return 是否删除成功
         */
        public boolean remove(E item) {
            Node<E> now = first;
            while (now != null) {
                if (now.value == item) {
                    if (now == first)
                        first = first.next;
                    else if (now == last)
                        last = last.prev;
                    now.prev = now.next = null;
                    --list.size;
                    return true;
                }
                now = now.next;
            }
            return false;
        }

        /**
         * 在头部添加一个元素
         *
         * @param item 需要添加的元素
         */
        public void addFirst(E item) {
            Node<E> node = new Node<>(item);
            if (first == null) {
                first = last = node;
                return;
            }
            node.next = first;
            first = first.prev = node;
            ++list.size;
        }

        /**
         * 向尾部添加一个元素
         *
         * @param item 需要添加的元素
         */
        public void addLast(E item) {
            Node<E> node = new Node<>(item);
            if (first == null) {
                first = last = node;
                ++list.size;
                return;
            }
            node.prev = last;
            last = last.next = node;
            ++list.size;
        }

        /**
         * 一下层
         *
         * @return 下一层
         */
        public Layer<E> next() {
            if (next == null) {
                next = list.last = new Layer<>(list);
                next.prev = this;
            }
            return next;
        }
    }

    /**
     * 节点
     *
     * @param <T> 值
     */
    private static class Node<T> {
        private Node<T> prev;// 上一个节点
        private Node<T> next;// 下一个节点
        public T value;

        public Node(T value) {
            this.value = value;
        }
    }
}
